// Package main 演示GORM的一对多关联关系操作
// 本示例展示了如何在GORM中定义、创建、查询具有一对多关联关系的数据
// 具体演示了GirlModel（一）和BoyModel（多）之间的一对多关联操作
package main

import (
	"gin-gorm/global"
	"gin-gorm/models"
)

// oneToMany 演示GORM的一对多关联关系操作
// 该函数包含多种一对多关联操作的示例：
// 1. 创建主表记录并级联创建多个从表记录
// 2. 创建主表记录并关联已有从表记录
// 3. 创建从表记录并关联已有主表记录
// 4. 查询主表记录并预加载关联的从表记录
// 5. 查询主表记录并根据条件预加载关联的从表记录
// 6. 单独查询关联记录
func oneToMany() {
	// 来了一个女神，自带俩舔狗
	// 创建GirlModel记录并级联创建多个关联的BoyModel记录
	// 这种方式会同时创建GirlModel和其关联的多个BoyModel记录
	// err := global.DB.Create(&models.GirlModel{
	// 	Name: "小露",
	// 	BoyList: []models.BoyModel{
	// 		{Name: "一号"},
	// 		{Name: "二号"},
	// 	},
	// }).Error
	// fmt.Println(err)

	// 来了一个女神，选了一个舔狗 关联已有男孩记录（ID=2）到新创建女孩记录
	// 创建GirlModel记录并关联已存在的BoyModel记录
	// 这种方式仅创建GirlModel记录，并将其与已存在的BoyModel记录（ID=2）关联
	// err := global.DB.Create(&models.GirlModel{
	// 	Name: "小张",
	// 	BoyList: []models.BoyModel{
	// 		{ID: 2}, // 仅指定ID，关联已有记录
	// 	},
	// }).Error
	// fmt.Println(err)

	// 来了一个舔狗，选了一个女神
	// 创建BoyModel记录并关联已存在的GirlModel记录
	// 这种方式创建BoyModel记录，并通过设置外键字段GirlID将其关联到已存在的GirlModel记录（ID=2）
	// err := global.DB.Create(&models.BoyModel{
	// 	Name:   "三号",
	// 	GirlID: 2, // 通过外键字段关联已有的GirlModel记录
	// }).Error
	// fmt.Println(err)

	// 查询小张的舔狗
	// 查询主表记录并预加载所有关联的从表记录
	// 通过Preload方法一次性加载GirlModel及其关联的所有BoyModel记录
	// var girl models.GirlModel
	// global.DB.Preload("BoyList").Take(&girl, "name = ?", "小张") // 预加载所有关联的BoyList
	// fmt.Println(girl.Name, girl.BoyList, len(girl.BoyList)) // 输出女孩名称、她的所有舔狗以及舔狗数量

	// 条件
	// 查询主表记录并根据条件预加载关联的从表记录
	// 通过在Preload方法中添加条件，只加载满足特定条件的关联记录
	// var girl models.GirlModel
	// global.DB.Preload("BoyList", "name = ?", "三号").Take(&girl, "name = ?", "小张") // 仅预加载名称为"三号"的Boy记录
	// fmt.Println(girl.Name, girl.BoyList, len(girl.BoyList)) // 输出女孩名称、满足条件的舔狗以及数量

	// 专门查关联
	// 单独查询主表记录的关联记录，而不加载主表的所有数据
	// 这种方式适用于只需要关联记录而不需要主表完整数据的场景
	// girl := models.GirlModel{}
	// global.DB.Take(&girl, "name = ?", "小张") // 先获取主表记录
	// var boyList []models.BoyModel

	// 使用Model和Association方法专门查询关联记录
	// global.DB.Model(&girl).Association("BoyList").Find(&boyList)
	// fmt.Println(boyList) // 输出查询到的关联记录

	// 小张 不舔了，换成了3号
	// girl := models.GirlModel{}
	// global.DB.Take(&girl, "name = ?", "小张")
	// global.DB.Model(&girl).Association("BoyList").Replace([]models.BoyModel{
	// 	{ID: 1},
	// })

	// 都不舔了
	// girl := models.GirlModel{}
	// global.DB.Take(&girl, "name = ?", "小张")
	// global.DB.Model(&girl).Association("BoyList").Clear()

	// 1, 3号又开始舔小张了
	// girl := models.GirlModel{}
	// global.DB.Take(&girl, "name = ?", "小张")
	// global.DB.Model(&girl).Association("BoyList").Append([]models.BoyModel{
	// 	{ID: 1},
	// 	{ID: 3},
	// })

	// 只有3号退出了
	girl := models.GirlModel{}
	global.DB.Take(&girl, "name = ?", "小张")
	global.DB.Model(&girl).Association("BoyList").Delete([]models.BoyModel{
		{ID: 3},
	})

}

// main 程序入口函数
// 初始化数据库连接并调用oneToMany函数进行一对多关联操作演示
func main() {
	// 初始化数据库连接
	global.Connect()
	// global.Migrate() // 可选：如果需要执行数据库迁移操作
	oneToMany() // 调用oneToMany函数执行一对多关联操作演示
}
